home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / arm / util / procName.py < prev    next >
Encoding:
Python Source  |  2012-05-18  |  3.9 KB  |  118 lines

  1. """
  2. Module to allow for arbitrary renaming of our python process. This is mostly
  3. based on:
  4. http://www.rhinocerus.net/forum/lang-python/569677-setting-program-name-like-0-perl.html#post2272369
  5. and an adaptation by Jake: https://github.com/ioerror/chameleon
  6.  
  7. A cleaner implementation is available at:
  8. https://github.com/cream/libs/blob/b38970e2a6f6d2620724c828808235be0445b799/cream/util/procname.py
  9. but I'm not quite clear on their implementation, and it only does targeted
  10. argument replacement (ie, replace argv[0], argv[1], etc but with a string
  11. the same size).
  12. """
  13.  
  14. import sys
  15. import ctypes
  16. import ctypes.util
  17.  
  18. # flag for setting the process name, found in '/usr/include/linux/prctl.h'
  19. PR_SET_NAME = 15
  20.  
  21. argc_t = ctypes.POINTER(ctypes.c_char_p)
  22.  
  23. Py_GetArgcArgv = ctypes.pythonapi.Py_GetArgcArgv
  24. Py_GetArgcArgv.restype = None
  25. Py_GetArgcArgv.argtypes = [ctypes.POINTER(ctypes.c_int),
  26.                            ctypes.POINTER(argc_t)]
  27.  
  28. # tracks the last name we've changed the process to
  29. currentProcessName = None
  30. maxNameLength = -1
  31.  
  32. def renameProcess(processName):
  33.   """
  34.   Renames our current process from "python <args>" to a custom name.
  35.   
  36.   Arguments:
  37.     processName - new name for our process
  38.   """
  39.   
  40.   _setArgv(processName)
  41.   if sys.platform == "linux2":
  42.     _setPrctlName(processName)
  43.   elif sys.platform == "freebsd7":
  44.     _setProcTitle(processName)
  45.  
  46. def _setArgv(processName):
  47.   """
  48.   Overwrites our argv in a similar fashion to how it's done in C with:
  49.   strcpy(argv[0], "new_name");
  50.   """
  51.   
  52.   global currentProcessName, maxNameLength
  53.   
  54.   argv = ctypes.c_int(0)
  55.   argc = argc_t()
  56.   Py_GetArgcArgv(argv, ctypes.pointer(argc))
  57.   
  58.   # The original author did the memset for 256, while Jake did it for the
  59.   # processName length (capped at 1608). I'm not sure of the reasons for
  60.   # either of these limits, but setting it to anything higher than than the
  61.   # length of the null terminated process name should be pointless, so opting
  62.   # for Jake's implementation on this.
  63.   
  64.   if currentProcessName == None:
  65.     # Getting argv via...
  66.     # currentProcessName = " ".join(["python"] + sys.argv)
  67.     # 
  68.     # doesn't do the trick since this will miss interpretor arguments like...
  69.     # python -W ignore::DeprecationWarning myScript.py
  70.     # 
  71.     # Hence we're fetching this via our ctypes argv. Alternatively we could
  72.     # use ps, though this is less desirable:
  73.     # "ps -p %i -o args" % os.getpid()
  74.     
  75.     args = []
  76.     for i in range(100):
  77.       if argc[i] == None: break
  78.       args.append(str(argc[i]))
  79.     
  80.     currentProcessName = " ".join(args)
  81.     maxNameLength = len(currentProcessName)
  82.   
  83.   if len(processName) > maxNameLength:
  84.     msg = "can't rename process to something longer than our initial name since this would overwrite memory used for the env"
  85.     raise IOError(msg)
  86.   
  87.   # space we need to clear
  88.   zeroSize = max(len(currentProcessName), len(processName))
  89.   
  90.   ctypes.memset(argc.contents, 0, zeroSize + 1) # null terminate the string's end
  91.   ctypes.memmove(argc.contents, processName, len(processName))
  92.   currentProcessName = processName
  93.  
  94. def _setPrctlName(processName):
  95.   """
  96.   Sets the prctl name, which is used by top and killall. This appears to be
  97.   Linux specific and has the max of 15 characters. Source:
  98.   http://stackoverflow.com/questions/564695/is-there-a-way-to-change-effective-process-name-in-python/923034#923034
  99.   """
  100.   
  101.   libc = ctypes.CDLL(ctypes.util.find_library("c"))
  102.   nameBuffer = ctypes.create_string_buffer(len(processName)+1)
  103.   nameBuffer.value = processName
  104.   libc.prctl(PR_SET_NAME, ctypes.byref(nameBuffer), 0, 0, 0)
  105.  
  106. def _setProcTitle(processName):
  107.   """
  108.   BSD specific calls (should be compataible with both FreeBSD and OpenBSD:
  109.   http://fxr.watson.org/fxr/source/gen/setproctitle.c?v=FREEBSD-LIBC
  110.   http://www.rootr.net/man/man/setproctitle/3
  111.   """
  112.   
  113.   libc = ctypes.CDLL(ctypes.util.find_library("c"))
  114.   nameBuffer = ctypes.create_string_buffer(len(processName)+1)
  115.   nameBuffer.value = processName
  116.   libc.setproctitle(ctypes.byref(nameBuffer))
  117.  
  118.